﻿#include "MyOpenGL.h"
#include <QOpenGLShaderProgram>

#define STRINGIZE(x) #x
#define SHADER(shader) "" STRINGIZE(shader)

MyOpenGL::MyOpenGL(QWidget *parent)
    : QOpenGLWidget(parent)
{

}

MyOpenGL::~MyOpenGL()
{

}

void MyOpenGL::initializeGL()
{
    // 为当前环境初始化OpenGL函数
    initializeOpenGLFunctions();

    // 创建顶点着色器
    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc = SHADER(
        in vec4 vPosition;
        void main()
        {
            gl_Position = vPosition;
        }
    );

    vshader->compileSourceCode(vsrc);

    // 创建片元着色器
    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc = SHADER(
        void main()
        {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        }
    );

    fshader->compileSourceCode(fsrc);

    // 创建着色器程序
    program = new QOpenGLShaderProgram;
    program->addShader(vshader);
    program->addShader(fshader);

    program->link();
    program->bind();
}

void MyOpenGL::paintGL()
{
    int w = width();
    int h = height();
    int side = qMin(w, h);
    glViewport((w - side)/2, (h - side)/2, side, side);

    // 清除屏幕
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 顶点位置
    GLfloat vertices[] = {
        -0.8f, 0.8f,
        -0.8f, -0.8f,
        0.8f, -0.8f,
        0.8f, 0.8f
    };

    // 返回变量在着色器程序参数列表中的位置。
    GLuint vPosition = program->attributeLocation("vPosition");
    // 将vPosition 于顶点数组vertices进行关联
    /*
     * glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
     * index： 设置着色器中变量索引
     * size: 表示每个顶点需要更新的分量数目
     * type: 指定数组中元素的类型
     * normalized: 设置顶点数据在存储前是否需要进行归一化
     * stride: 是数组中每个元素之间的大小偏移值一般设置为0
     * pointer: 设置顶点数组指针或者缓存内的偏移量
    */
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    /* 启用顶点数组 */
    glEnableVertexAttribArray(vPosition);

    // 绘制
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

void MyOpenGL::resizeGL(int w, int h)
{

}
